package extension

import android.os.Bundle
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager

fun obtainFragment(
    fragmentManager: FragmentManager,
    clazz: Class<out Fragment>,
    tag: String? = null
): Fragment {
    var fragment: Fragment? = fragmentManager.findFragmentByTag(tag ?: clazz.simpleName)
    if (fragment == null) {
        fragment = clazz.newInstance()
    }
    return fragment!!
}

fun addFragment(
    fragmentManager: FragmentManager,
    containerId: Int,
    clazz: Class<out Fragment>,
    tag: String? = null,
    bundle: Bundle? = null,
    isHide: Boolean = false
): Fragment {
    var fragment: Fragment? = fragmentManager.findFragmentByTag(tag ?: clazz.simpleName)
    if (fragment == null) {
        fragment = clazz.newInstance()
        fragmentManager.beginTransaction()
            .add(containerId, fragment, tag ?: clazz.simpleName)
            .apply { if (isHide) hide(fragment) }
            .commitAllowingStateLoss()
    }
    bundle?.let {
        fragment!!.arguments = bundle
    }
    return fragment!!
}

fun addFragments(
    fragmentManager: FragmentManager,
    containerId: Int,
    vararg fragmentData: FragmentWrapper
) {
    if (fragmentData.isEmpty()) return

    val transaction = fragmentManager.beginTransaction()
    fragmentData.forEach {
        var fragment: Fragment? =
            fragmentManager.findFragmentByTag(it.tag /*?: it.clazz.simpleName*/)
        if (fragment == null) {
            fragment = it.clazz.newInstance()
            transaction
                .add(containerId, fragment, it.tag/* ?: it.clazz.simpleName*/)
                .apply { if (it.isHide) hide(fragment) }
        }
        it.bundle?.let { params ->
            fragment!!.arguments = params
        }
    }
    transaction.commitAllowingStateLoss()
}

/**
 * 显示指定tag对应的fragment
 * @param clazz 优先取clazz.simpleName作为tag
 * @param tag clazz为空，则取tag
 * @param hideOther 是否隐藏fragmentManager中其他fragment
 */
fun showFragment(
    fragmentManager: FragmentManager,
    containerId: Int,
    clazz: Class<out Fragment>? = null,
    tag: String? = null,
    hideOther: Boolean = true
) {
    val realTag = clazz?.simpleName ?: tag ?: return
    // 应该查询对应容器的fragment
    fragmentManager.fragments.filter { it.id == containerId }.forEach {
        fragmentManager.beginTransaction().apply {
            if (it.tag == realTag) {
                if (it.isHidden) show(it)
            } else if (hideOther && !it.isHidden) {
                hide(it)
            }
        }.commitAllowingStateLoss()
    }
}

/**
 * 隐藏指定tag对应的Fragment
 */
fun hideFragment(
    fragmentManager: FragmentManager,
    clazz: Class<out Fragment>? = null,
    tag: String? = null
) {
    val realTag = clazz?.simpleName ?: tag ?: return
    fragmentManager.fragments.find { it.tag == realTag }?.let {
        fragmentManager.beginTransaction().hide(it).commitAllowingStateLoss()
    }
}

data class FragmentWrapper(
    val clazz: Class<out Fragment>,
    var tag: String? = null,
    val bundle: Bundle? = null,
    val isHide: Boolean = true
) {
    init {
        if (tag == null) {
            tag = clazz.simpleName
        }
    }
}